﻿using DevExpress.Data.Filtering;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Filtering;
using DevExpress.ExpressApp.Model;

namespace EasyXaf.FullTextSearch;

public class FullTextSearchCriteriaBuilder : SearchCriteriaBuilder
{
    private readonly IModelApplication _applicationModel;

    public FullTextSearchCriteriaBuilder(IModelApplication applicationModel)
    {
        _applicationModel = applicationModel;
    }

    private IModelFullTextSearch GetFullTextSearchModel(IMemberInfo memberInfo)
    {
        var classModel = _applicationModel.BOModel.GetClass(memberInfo.Owner.Type);
        var memberModel = classModel.FindMember(memberInfo.Name);
        return memberModel as IModelFullTextSearch;
    }

    protected override IMemberInfo GetActualSearchProperty(string propertyName)
    {
        var memberInfo = base.GetActualSearchProperty(propertyName);
        if (memberInfo != null && GetFullTextSearchModel(memberInfo).DisableSearch)
        {
            return null;
        }
        return memberInfo;
    }

    protected override CriteriaOperator CreateCriteriaOperator(IMemberInfo memberInfo, string valueToSearch)
    {
        if (memberInfo.MemberType == typeof(string))
        {
            // EnableFullTextSearch优先级最高
            // 没有设置EnableFullTextSearch时，含有FullTextSearchAttribute表示启用，否则不启用
            // 设置EnableFullTextSearch时，根据EnableFullTextSearch的值判断是否启用
            var enableFullTextSearch = memberInfo.FindAttribute<FullTextSearchAttribute>() != null;
            var fullTextSearchModel = GetFullTextSearchModel(memberInfo);
            if (fullTextSearchModel.EnableFullTextSearch.HasValue)
            {
                enableFullTextSearch = fullTextSearchModel.EnableFullTextSearch.Value;
            }
            if (enableFullTextSearch)
            {
                return new FunctionOperator("FullTextContains", new OperandProperty(memberInfo.Name), new OperandValue(valueToSearch.Trim()));
            }
        }
        return base.CreateCriteriaOperator(memberInfo, valueToSearch);
    }
}
